#ifndef VIDEOTHREAD_HXX
#define VIDEOTHREAD_HXX
#include <stdio.h>
#include<iostream>

#ifdef _WIN64
#include<Windows.h>
#endif

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/core/ocl.hpp>


extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}

#include <QThread>
#include "FramePool.hxx"

class Sequence;

enum VideoStatus
{
	VT_STATUS_UNKOWN = 0,
	VT_STATUS_PLAYING,
	VT_STATUS_STEPPING,
	VT_STATUS_GOFRAME,
	VT_STATUS_PAUSED,
	VT_STATUS_STOPPED,
	VT_STATUS_FINISHED
};

//enum VideoAction
//{
//	ACTION_NONE = 0,
//	ACTION_GO_FRAME
//};

//enum ActionStatus
//{
//	AT_STATUS_UNKOWN = 0,
//	AT_STATUS_READY,
//	AT_STATUS_RUNNING,
//	AT_STATUS_FINISHED
//};

struct VideoFrameInfo
{
	int FrameIndex;
	double TimeStamp;
	int Width;
	int Height;

	VideoFrameInfo()
	{
		FrameIndex = -1;
		TimeStamp = 0.0;
		Width = 0;
		Height = 0;
	}
};

class VideoThread : public QThread
{
    Q_OBJECT
public:
    VideoThread();
	~VideoThread();

    void run() override;

    void initialize();

	//inline void stop() { _stopFlag = true; }
	inline void stop() { _videoStatus = VT_STATUS_STOPPED; }
	inline void pause() { _videoStatus = VT_STATUS_PAUSED; }
	inline void resume() { _videoStatus = VT_STATUS_PLAYING; }
	inline void next() { _videoStatus = VT_STATUS_STEPPING; }

	inline bool isStoped() { return _videoStatus == VT_STATUS_STOPPED; }

	void actionGoFrame(int frameIndex);

    inline void setFramePool(FramePool* pool) { _framePool = pool;}
    inline void setVideoModel(Sequence* model) { _model = model;}

	//inline void setTargetFrameIndex(int index) { _targetFrameIndex = index; }
	//inline int getTargetFrameIndex() { return _targetFrameIndex; }

	void testFunc();
	void decodeVideo();

	inline bool isPaused() { return _videoStatus == VT_STATUS_PAUSED; }

private:
	void enableOrderCheck();
	void disableOrderCheck();
	bool doOrderCheck(const int findex);

	

private:
    AVFormatContext *pFormatCtx;
    int              videoindex;
    AVCodecContext  *pCodecCtx;
    AVCodec         *pCodec;

	//bool _stopFlag;
	//bool _pauseFlag;

    FramePool* _framePool;
    Sequence* _model;

	VideoStatus _videoStatus;

	VideoFrameInfo _videoFrameInfo;
	char* _videoFrameBuffer;

	int _targetFrameIndex;
//	bool _pauseOnFrameFlag;

	bool _needOrderCheck;
};

#endif // VIDEOTHREAD_HXX
